package aclInfoCollector.filesAnalysers.jarFile;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.InputStream;
import java.io.OutputStream;

import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;

import javax.swing.JLabel;

import aclInfoCollector.filesAnalysers.code.classFile.ClassFileAnalyser;
import aclInfoCollector.filesAnalysers.code.javaFile.JavaAnalyser;
import aclInfoCollector.filesAnalysers.component.fractalFile.FractalAnalyser;

import aclInfoCollector.utils.extensionsFilters.DotJarFilter;

/**
 * La classe JarFinder permet de reunir les informations contenus dans des
 * archives jar
 * 
 * @version 1.0
 *@author Bendavid Olivier
 *@author Haderer Nicolas
 */

public class JarAnalyser {
	public static void main(String args[]) {
		System.out.println("debut");
		System.out.println();
		JarAnalyser jf = new JarAnalyser("fractalexplorer");
		//jf.printSummary();
		
		
		for(String s : jf.getClassAnalyser().getClasses())
		{
			System.out.println("en commun  : "+s);
	
		}
		
		System.out.println();
		System.out.println("fin");

	}
	private ClassFileAnalyser classAnalyser;
	private JavaAnalyser javaAnalyser;
	private FractalAnalyser fractalAnalyser;

	public JarAnalyser() {

		classAnalyser = new ClassFileAnalyser();
		javaAnalyser = new JavaAnalyser();
		fractalAnalyser = new FractalAnalyser();
	}

	public JarAnalyser(String directoryPath) {
		classAnalyser = new ClassFileAnalyser();
		javaAnalyser = new JavaAnalyser();
		fractalAnalyser = new FractalAnalyser();
		launchAnalysis(directoryPath);
	}

	/**
	 * @return the classFinder
	 */
	public ClassFileAnalyser getClassAnalyser() {
		return classAnalyser;
	}

	/**
	 * @return the FractalFinder
	 */
	public FractalAnalyser getFractalAnalyser() {
		return fractalAnalyser;
	}

	/**
	 * @return the javaFinder
	 */
	public JavaAnalyser getJavaAnalyser() {
		return javaAnalyser;
	}

	/**
	 * Recherche tous les fichiers .jar et les parse
	 * 
	 * @param directoryPath
	 *            est le repertoire dans lequel on souhaite effecuter la
	 *            recherche
	 */
	public void launchAnalysis(String directoryPath) {
		File directoryToScan = new File(directoryPath);
		File[] Files = directoryToScan.listFiles();
		FilenameFilter filter = new DotJarFilter();
		for (int i = 0; i < Files.length; i++) {
			if (Files[i].isDirectory()) {
				launchAnalysis(Files[i].getAbsolutePath());
			}
		}
		File[] FilesClass = directoryToScan.listFiles(filter);
		for (int i = 0; i < FilesClass.length; i++) {
			parse(FilesClass[i]);
		}

	}

	/**
	 * analyse le contenu d'un fichier jar
	 * 
	 * @param path
	 *            le fichier jar a parser
	 */
	public void parse(File ff) {
		File temp = new File("temp/");
		temp.mkdir();

		try {
			JarFile jar = new JarFile(ff.getAbsolutePath());
			Enumeration<JarEntry> e = jar.entries();
			while (e.hasMoreElements()) {
				ZipEntry entry = e.nextElement();
				if (!entry.isDirectory()) {
					File efile = new File("temp/", entry.getName().substring(
							entry.getName().toString().lastIndexOf("/") + 1));
					InputStream in = new BufferedInputStream(jar
							.getInputStream(entry));
					OutputStream out = new BufferedOutputStream(
							new FileOutputStream(efile));
					byte[] buffer = new byte[2048];
					for (;;) {
						int nBytes = in.read(buffer);
						if (nBytes <= 0)
							break;
						out.write(buffer, 0, nBytes);
					}
					out.flush();
					out.close();
					in.close();

					if (entry.getName().substring(
							entry.getName().toString().lastIndexOf("/") + 1)
							.endsWith(".class")) {
						classAnalyser.parse(efile);
						efile.delete();

					} 
					else if (entry.getName().substring(
							entry.getName().toString().lastIndexOf("/") + 1)
							.endsWith(".java")) {
						javaAnalyser.parse(efile);
						efile.delete();

					} else if (entry.getName().substring(
							entry.getName().toString().lastIndexOf("/") + 1)
							.endsWith(".fractal")) {
						fractalAnalyser.parseFractalFile(efile);
						efile.delete();

					} else if (entry.getName().substring(
							entry.getName().toString().lastIndexOf("/") + 1)
							.endsWith(".jar")) {
						parse(efile.getAbsolutePath());
						efile.delete();
					} else {
						efile.delete();
					}

				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * analyse le contenu d'un fichier jar
	 * 
	 * @param path
	 *            le chemin du jar parser
	 */

	public void parse(String path) {
		File temp = new File("temp/");
		temp.mkdir();

		try {
			JarFile jar = new JarFile(path);
			Enumeration<JarEntry> e = jar.entries();
			while (e.hasMoreElements()) {
				ZipEntry entry = e.nextElement();
				if (!entry.isDirectory()) {
					File efile = new File("temp/", entry.getName().substring(
							entry.getName().toString().lastIndexOf("/") + 1));
					InputStream in = new BufferedInputStream(jar
							.getInputStream(entry));
					OutputStream out = new BufferedOutputStream(
							new FileOutputStream(efile));
					byte[] buffer = new byte[2048];
					for (;;) {
						int nBytes = in.read(buffer);
						if (nBytes <= 0)
							break;
						out.write(buffer, 0, nBytes);
					}
					out.flush();
					out.close();
					in.close();

					if (entry.getName().substring(
							entry.getName().toString().lastIndexOf("/") + 1)
							.endsWith(".class")) {
						classAnalyser.parse(efile);
						efile.delete();

					}
//					else if (entry.getName().substring(
//							entry.getName().toString().lastIndexOf("/") + 1)
//							.endsWith(".java")) {
//						javaAnalyser.parse(efile);
//						efile.delete();
//
//					} 
//					
//					else if (entry.getName().substring(
//							entry.getName().toString().lastIndexOf("/") + 1)
//							.endsWith(".fractal")) {
//						fractalAnalyser.parseFractalFile(efile);
//						efile.delete();
//
//					}
					
					else if (entry.getName().substring(
							entry.getName().toString().lastIndexOf("/") + 1)
							.endsWith(".jar")) {
						parse(efile.getAbsolutePath());
						efile.delete();
					} else {
						efile.delete();
					}

				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * affiche le résumé des éléments analysés
	 */

	public void printSummary() {
		javaAnalyser.printSummary();
		classAnalyser.printSummary();
		fractalAnalyser.printSummary();
	}

	public void launchAnalysis(String directoryPath, JLabel label) {
		File directoryToScan = new File(directoryPath);
		File[] Files = directoryToScan.listFiles();
		FilenameFilter filter = new DotJarFilter();
		for (int i = 0; i < Files.length; i++) {
			if (Files[i].isDirectory()) {
				launchAnalysis(Files[i].getAbsolutePath());
			}
		}
		File[] FilesClass = directoryToScan.listFiles(filter);
		for (int i = 0; i < FilesClass.length; i++) {
			parse(FilesClass[i],label);
		}
		
	}

	public void parse(File ff, JLabel label) {
		label.setText(ff.getAbsolutePath());
		label.repaint();
		File temp = new File("temp/");
		temp.mkdir();

		try {
			JarFile jar = new JarFile(ff.getAbsolutePath());
			Enumeration<JarEntry> e = jar.entries();
			while (e.hasMoreElements()) {
				ZipEntry entry = e.nextElement();
				if (!entry.isDirectory()) {
					File efile = new File("temp/", entry.getName().substring(
							entry.getName().toString().lastIndexOf("/") + 1));
					InputStream in = new BufferedInputStream(jar
							.getInputStream(entry));
					OutputStream out = new BufferedOutputStream(
							new FileOutputStream(efile));
					byte[] buffer = new byte[2048];
					for (;;) {
						int nBytes = in.read(buffer);
						if (nBytes <= 0)
							break;
						out.write(buffer, 0, nBytes);
					}
					out.flush();
					out.close();
					in.close();

					if (entry.getName().substring(
							entry.getName().toString().lastIndexOf("/") + 1)
							.endsWith(".class")) {
						classAnalyser.parse(efile);
						efile.delete();

					} 
					else if (entry.getName().substring(
							entry.getName().toString().lastIndexOf("/") + 1)
							.endsWith(".java")) {
						javaAnalyser.parse(efile);
						efile.delete();

					} else if (entry.getName().substring(
							entry.getName().toString().lastIndexOf("/") + 1)
							.endsWith(".fractal")) {
						fractalAnalyser.parseFractalFile(efile);
						efile.delete();

					} else if (entry.getName().substring(
							entry.getName().toString().lastIndexOf("/") + 1)
							.endsWith(".jar")) {
						parse(efile.getAbsolutePath());
						efile.delete();
					} else {
						efile.delete();
					}

				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}

}
